﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Runtime.Remoting.Messaging;

namespace AsyncDelegate
{
    class Program
    {
        public delegate int AddOp(int x, int y);

        private static bool isComplete = false;

        static void Main(string[] args)
        {
            Console.WriteLine("Start Main()");

            AddOp add = new AddOp(Add);
            IAsyncResult ar = add.BeginInvoke(3, 7, new AsyncCallback(AddComplete), null);
            Console.WriteLine("Doing another thing...(This show immediately)");

            while (!isComplete)
            {
                Thread.Sleep(1000);
                Console.WriteLine("waiting...");
            }

            // Method EndInvoke can be invoked only once.
            //int result = add.EndInvoke(ar);
            //Console.WriteLine("Result=" + result);
        }

        public static int Add(int x, int y)
        {
            Console.WriteLine("Invoke Add(). Please wait...");

            Thread.Sleep(5000);

            return x + y;
        }

        public static void AddComplete(IAsyncResult result)
        {
            Console.WriteLine("Add complete");
            AsyncResult a = (AsyncResult)result;
            AddOp add = (AddOp)a.AsyncDelegate;
            Console.WriteLine("Result in AddComplete=" + add.EndInvoke(result));

            isComplete = true;
        }
    }
}
